package emu.decvices.cartridge.mappers;

import emu.decvices.bus.BusDevice;
import emu.decvices.cartridge.Cartridge;

public class Mapper003 extends Mapper{
    private int register;
    public Mapper003(Cartridge cartridge) {
        super(cartridge);
    }

    private CpuDevice cpuDevice = new CpuDevice();
    private PpuDevice ppuDevice = new PpuDevice();

    @Override
    public BusDevice getCpuDevice() {
        return cpuDevice;
    }

    @Override
    public BusDevice getPpuDevice() {
        return ppuDevice;
    }

    private class PpuDevice extends BusDevice{

        @Override
        public int fromDeviceRead(int address) {
            if(address<0x2000){
               return chrData[register*0x2000+address];
            }
            return -1;
        }

    }

    private class CpuDevice extends BusDevice{

        //PRG只有1块时，后16k地址映射为前16k地址
//        private int offset = romHeader.getPrgRomChunks()>1?0x8000:0xC000;
        @Override
        public int fromDeviceRead(int address) {
            //CPU可寻址prgRom的总线地址范围
//            if(address>=0x8000 && address<=0xFFFF) {
//                return prgData[address-offset]&0xFF;
//            }
//            return -1;
            if(address>=0x8000 && address<=0xFFFF) {
                if(romHeader.getPrgRomChunks()>1){
                    return prgData[address&0x7FFF]&0xFF;
                }else{
                    return prgData[address&0x3FFF]&0xFF;
                }

            }
            return -1;

        }

        /**
         * Registers
         * Bank select ($8000-$FFFF)
         * 7  bit  0
         * ---- ----
         * cccc ccCC
         * |||| ||||
         * ++++-++++- Select 8 KB CHR ROM bank for PPU $0000-$1FFF
         * CNROM only implements the lowest 2 bits, capping it at 32 KiB CHR. Other boards may implement 4 or more bits for larger CHR.
         * @param address
         * @param data
         * @return
         */
        @Override
        public boolean toDeviceWrite(int address, int data) {
            if(address>=0x8000 && address<=0xFFFF) {
                register = data&(romHeader.getChrRomChunks()-1);
                return true;
            }
            return false;
        }
    }
}
